home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / gemfsc20 / gemfsc20.lzh / GEMFUNCS / FRMDSDIA.C < prev    next >
C/C++ Source or Header  |  1993-03-20  |  10KB  |  278 lines

  1. /**************************************************************************
  2.  * FRMDSDIA.C - frm_dsdialog(): dynamic string dialog routine.
  3.  *************************************************************************/
  4.  
  5. #include "gemfintl.h"
  6. #include <string.h>
  7.  
  8. static char *default_buttons[] = {" Continue ",     NULL};
  9. static char *default_strings[] = {"<no message>",   NULL};
  10.  
  11. /*-------------------------------------------------------------------------
  12.  * Object tree for dynamic dialog box...
  13.  *-----------------------------------------------------------------------*/
  14.  
  15. #define OUTLINED_BOX_SPEC 0x00021100L
  16. #define SHADOWED_BOX_SPEC 0x00FF1100L
  17.  
  18. static OBJECT GFAR dialtree[] = {
  19.   -1,  1, 21, G_BOX,    NONE,    OUTLINED, (_Ob_spec_t)0x00021100L,0x0000, 0x0000, 0x0021, 0x0017,
  20.    2, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0001, 0x0001, 0x0001,
  21.    3, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0002, 0x0001, 0x0001,
  22.    4, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0003, 0x0001, 0x0001,
  23.    5, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0004, 0x0001, 0x0001,
  24.    6, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0005, 0x0001, 0x0001,
  25.    7, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0006, 0x0001, 0x0001,
  26.    8, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0007, 0x0001, 0x0001,
  27.    9, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0008, 0x0001, 0x0001,
  28.   10, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0009, 0x0001, 0x0001,
  29.   11, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000A, 0x0001, 0x0001,
  30.   12, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000B, 0x0001, 0x0001,
  31.   13, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000C, 0x0001, 0x0001,
  32.   14, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000D, 0x0001, 0x0001,
  33.   15, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000E, 0x0001, 0x0001,
  34.   16, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x000F, 0x0001, 0x0001,
  35.   17, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0010, 0x0001, 0x0001,
  36.   18, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0011, 0x0001, 0x0001,
  37.   19, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0012, 0x0001, 0x0001,
  38.   20, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0013, 0x0001, 0x0001,
  39.   21, -1, -1, G_STRING, NONE,    NORMAL,   (_Ob_spec_t)0L,          0x0001, 0x0014, 0x0001, 0x0001,
  40.    0, 22, 26, G_IBOX,    NONE,    NORMAL,   (_Ob_spec_t)0x00001100L,0x0001, 0x0015, 0x0001, 0x0001,
  41.   23, -1, -1, G_BUTTON, 0x0005, NORMAL,   (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001,
  42.   24, -1, -1, G_BUTTON, 0x0005, NORMAL,   (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001,
  43.   25, -1, -1, G_BUTTON, 0x0005, NORMAL,   (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001,
  44.   26, -1, -1, G_BUTTON, 0x0005, NORMAL,   (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001,
  45.   21, -1, -1, G_BUTTON, 0x0025, NORMAL,   (_Ob_spec_t)0L,          0x0000, 0x0000, 0x0001, 0x0001
  46.   };
  47.  
  48. #define DIALSTL1 1        /* String Line 1                */
  49. #define DIALPBXB 21     /* Parent Box for exit buttons    */
  50. #define DIALBX01 22     /* First exit button            */
  51.  
  52. /*----------------------------------------------------------------------------
  53.  * count_strings - Count strings and keep track of the longest one.
  54.  *--------------------------------------------------------------------------*/
  55.  
  56. #ifdef GEMFAST_PROTOS
  57.   static short count_strings(char **pstrings, short maxstrings, short *pmaxlen)
  58. #else
  59.   static short count_strings(pstrings, maxstrings, pmaxlen)
  60.     register char    **pstrings;
  61.     register short      maxstrings;
  62.     short              *pmaxlen;
  63. #endif
  64. {
  65.     register short      numstrings;
  66.     register size_t   wrklen;
  67.     register size_t   maxlen;
  68.  
  69.     for (numstrings = 0, maxlen = 0;
  70.          numstrings < maxstrings && *pstrings && **pstrings != 0x00;
  71.          ++numstrings,
  72.          ++pstrings) {
  73.  
  74.             if (maxlen < (wrklen = strlen(*pstrings))) {
  75.                 maxlen = wrklen;
  76.             }
  77.     }
  78.  
  79.     *pmaxlen = (short)maxlen;
  80.     return numstrings;
  81. }
  82.  
  83. /**************************************************************************
  84.  * frm_dsdial - Form dynamic string dialog.
  85.  *************************************************************************/
  86.  
  87. short frm_dsdialog(options, pbuttons, pstrings)
  88.     long             options;
  89.     char             *pbuttons[];
  90.     char             *pstrings[];
  91. {
  92.     short               xbwidth;
  93.     short               slen;
  94.     register short       sizechar;
  95.     register short       counter;
  96.     register short       numobs;
  97.     register short       pixlen;
  98.     register OBJECT  *ptree;
  99.     register char     **pwrk;
  100.     static     short       initdone = 0;
  101.     static     short       l1_title_y;
  102.     static     short       l1_notitle_y;
  103.  
  104. /*-------------------------------------------------------------------------
  105.  * validate the parameters.
  106.  *-----------------------------------------------------------------------*/
  107.  
  108.     if (pstrings == NULL) {
  109.         pstrings = default_strings;
  110.     }
  111.  
  112.     if (pbuttons == NULL) {
  113.         pbuttons = default_buttons;
  114.     }
  115.  
  116.     if (!(options & FRM_NODEFAULTS)) {
  117.         options |= (_FrmDefaults & FRM_DOPTIONBITS) | FRM_DEFAULT_DYNOPT;
  118.     }
  119.     options |= FRM_MANDATORY_DYNOPT;
  120.  
  121. /*-------------------------------------------------------------------------
  122.  * Init the xywh values in the object tree, get the system character sizes
  123.  * for later usage, precalc possible top-line Y placements for later.
  124.  *-----------------------------------------------------------------------*/
  125.  
  126.     if (!initdone) {
  127.         initdone = TRUE;
  128.         rsc_treefix(dialtree);
  129.         l1_notitle_y = dialtree[DIALSTL1].ob_y;
  130.         l1_title_y     = l1_notitle_y - (gl_hchar >> 1);
  131.     }
  132.  
  133. /*-------------------------------------------------------------------------
  134.  * Count the button strings, find the longest one, distribute the buttons
  135.  * evenly within their parent box, make the rightmost the default button.
  136.  * (We place a gutter of 2 character widths on each side of each button.)
  137.  *-----------------------------------------------------------------------*/
  138.  
  139.     {
  140.         short            saw_default_button = FALSE;
  141.         char            *pbtn;
  142.         register short    obx;
  143.  
  144.         numobs = count_strings(pbuttons, FRM_DSMAXBUTTONS, &slen);
  145.  
  146.         sizechar  = gl_wchar;
  147.         pixlen      = (slen + 2) * sizechar;
  148.         sizechar *= 2;
  149.         xbwidth   = (numobs * pixlen) + ((numobs + 1) * sizechar);
  150.  
  151.         for (counter = 0, obx = sizechar, pwrk = pbuttons, ptree = &dialtree[DIALBX01];
  152.              counter < FRM_DSMAXBUTTONS;
  153.              ++counter, obx += pixlen + sizechar, ++ptree) {
  154.  
  155.             ptree->ob_flags &= ~DEFAULT;
  156.  
  157.             if (counter < numobs) {
  158.                 pbtn = *pwrk++;
  159.                 ptree->ob_flags &= ~HIDETREE;
  160.                 ptree->ob_x     = obx;
  161.                 if (*pbtn == 0x7F) {
  162.                     ptree->ob_flags |= DEFAULT;
  163.                     ++pbtn;
  164.                     ++saw_default_button;
  165.                 }
  166.                 ptree->_Ob_spec  = (_Ob_spec_t)pbtn;
  167.                 ptree->ob_width = pixlen;
  168.             } else {
  169.                 ptree->ob_flags |= HIDETREE;
  170.             }
  171.         }
  172.  
  173.         if (!(options & FRM_DMUSTSELECT) && !saw_default_button) {
  174.             if (options & FRM_DEFAULTLEFT) {
  175.                 numobs = 1; /* leftmost button is default                                */
  176.             }
  177.             dialtree[DIALPBXB+numobs].ob_flags |= DEFAULT;
  178.         }
  179.     }
  180.  
  181. /*-------------------------------------------------------------------------
  182.  * Count the dialog strings, find the largest, calc the size of the
  183.  * dialog box and the placement of the buttons at the bottom.  If space
  184.  * permits, we leave a 1-line gutter between the last dialog string and
  185.  * the buttons, but if all 20 dialog strings are used, then the buttons
  186.  * are jammed right up against the bottom string.
  187.  *-----------------------------------------------------------------------*/
  188.  
  189.     {
  190.         register short btnadjust;
  191.  
  192.         numobs      = count_strings(pstrings, FRM_DSMAXSTRINGS, &slen);
  193.  
  194.         btnadjust = (numobs < FRM_DSMAXSTRINGS); /* button padding, if space allows */
  195.  
  196.         pixlen      = (slen + 2) * gl_wchar;
  197.         pixlen      = (pixlen > xbwidth) ? pixlen : xbwidth;
  198.  
  199.         sizechar  = gl_hchar;
  200.  
  201.         ptree             = dialtree;
  202.         ptree->ob_width  = pixlen;
  203.         ptree->ob_height = ((numobs + 3 + btnadjust) * sizechar);
  204.  
  205.         ptree             = &dialtree[DIALPBXB];
  206.         ptree->ob_x      = (pixlen - xbwidth) >> 1;
  207.         ptree->ob_y      = ((numobs + 1 + btnadjust) * sizechar) + (sizechar >> 2);
  208.         ptree->ob_width  = xbwidth;
  209.     }
  210.  
  211. /*-------------------------------------------------------------------------
  212.  * Set the ob_width and ob_spec for all the active strings in the dialog
  213.  * box, set all the inactive strings to HIDETREE.  Center strings that
  214.  * start with 0x7F (and fix it so the 0x7F char isn't displayed).
  215.  *-----------------------------------------------------------------------*/
  216.  
  217.     {
  218.     register char *line;
  219.     register short    at_x;
  220.     register short    len;
  221.  
  222.         sizechar = gl_wchar;
  223.         for (counter = 0, pwrk    = pstrings, ptree = &dialtree[DIALSTL1];
  224.              counter < FRM_DSMAXSTRINGS;
  225.              ++counter, ++ptree) {
  226.  
  227.             if (counter < numobs) {
  228.                 ptree->ob_flags &= ~HIDETREE;
  229.                 line = *pwrk++;
  230.                 if (*line == 0x7F) {
  231.                     len  = sizechar * (short)strlen(++line);
  232.                     at_x = (pixlen - len) / 2;
  233.                 } else {
  234.                     len  = pixlen;
  235.                     at_x = sizechar;
  236.                 }
  237.                 ptree->_Ob_spec   = (_Ob_spec_t)line;
  238.                 ptree->ob_x      = at_x;
  239.                 ptree->ob_width  = len;
  240.  
  241.             } else {
  242.                 ptree->ob_flags |= HIDETREE;
  243.             }
  244.         }
  245.     }
  246.  
  247. /*-------------------------------------------------------------------------
  248.  * Handle the FRM_DSHADOWED and FRM_DSL1TITLE options.
  249.  *-----------------------------------------------------------------------*/
  250.  
  251.     ptree  = dialtree;
  252.  
  253.     if (options & FRM_DSHADOWED) {
  254.         ptree->ob_state = SHADOWED;
  255.         ptree->_Ob_spec  = (_Ob_spec_t)SHADOWED_BOX_SPEC;
  256.     } else {
  257.         ptree->ob_state = OUTLINED;
  258.         ptree->_Ob_spec  = (_Ob_spec_t)OUTLINED_BOX_SPEC;
  259.     }
  260.  
  261.     ptree[DIALSTL1].ob_y =
  262.         (options & FRM_DSL1TITLE) ? l1_title_y : l1_notitle_y;
  263.  
  264.  
  265. /*-------------------------------------------------------------------------
  266.  * Do dialog, return button number adjusted to range of 0-4.
  267.  *-----------------------------------------------------------------------*/
  268.  
  269.     {
  270.         short selection;
  271.  
  272.         selection = frm_dialog(options, ptree, ROOT);
  273.         return (selection - DIALBX01);
  274.  
  275.     }
  276. }
  277.  
  278.